package com.school.accessdoor;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import cn.hutool.core.util.ObjectUtil;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.web.multipart.MultipartFile;

import com.mhuang.school.starter.minio.core.MinioFrame;
import com.mhuang.school.starter.minio.util.ToolUtil;
import com.school.device.util.CaptureUtil;
import com.school.device.util.DataConvertUtil;
import com.school.device.util.MockMultipartFile;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HttpCaptureUtil {

	private static String getMD5Digest(String input) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			byte[] digest = md.digest(input.getBytes());
			StringBuilder sb = new StringBuilder();
			for (byte b : digest)
				sb.append(String.format("%02x", b));
			return sb.toString();
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException("Could not find MD5 algorithm", e);
		}
	}

	// 拉取门禁数据
	private static String getRecord(String ip, String username, String password, Integer number, Long startTime) {
		String url = "http://" + ip + "/cgi-bin/recordFinder.cgi?action=find&name=AccessControlCardRec&count=" + number + "&StartTime=" + (startTime + 1); // 开始 1738808263
		log.info("url:" + url);
		HttpResponse response = HttpRequest.get(url).execute();
		Map<String, List<String>> headers = response.headers();
		String authenticate = headers.get("WWW-Authenticate").get(0);
		String nonce = authenticate.split("nonce=\"")[1].split("\"")[0];
		String realm = authenticate.split("realm=\"")[1].split("\"")[0];
		// # 生成摘要身份验证的响应值
		String ha1 = getMD5Digest(username + ":" + realm + ":" + password);
		String ha2 = getMD5Digest("GET:" + url);
		String responses = getMD5Digest(ha1 + ":" + nonce + ":00000001:randomstring:auth:" + ha2);
		String authorizations = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + url + "\", qop=auth, nc=00000001, cnonce=\"randomstring\", response=\"" + responses + "\"";
		HttpResponse resp = HttpRequest.get(url).header("Content-Type", "application/json").header("Authorization", authorizations).execute();
		if (resp.isOk())
			return resp.body();
		return null;
	}

	// 拉取人脸数据
	private static String getFace(String ip, String username, String password, List<String> userIds) {
		if (userIds == null || userIds.size() == 0)
			return null;
		StringBuilder condition = new StringBuilder();
		int len = userIds.size();
		for (int i = 0; i < len; i++)
			condition.append("&UserIDList[" + i + "]=" + userIds.get(i));
		String url = "http://" + ip + "/cgi-bin/AccessFace.cgi?action=list" + condition.toString();// 拉取人脸
		HttpResponse response = HttpRequest.get(url).execute();
		Map<String, List<String>> headers = response.headers();
		String authenticate = headers.get("WWW-Authenticate").get(0);
		String nonce = authenticate.split("nonce=\"")[1].split("\"")[0];
		String realm = authenticate.split("realm=\"")[1].split("\"")[0];
		// # 生成摘要身份验证的响应值
		String ha1 = getMD5Digest(username + ":" + realm + ":" + password);
		String ha2 = getMD5Digest("GET:" + url);
		String responses = getMD5Digest(ha1 + ":" + nonce + ":00000001:randomstring:auth:" + ha2);
		String authorizations = "Digest username=\"" + username + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", uri=\"" + url + "\", qop=auth, nc=00000001, cnonce=\"randomstring\", response=\"" + responses + "\"";
		HttpResponse resp = HttpRequest.get(url).header("Content-Type", "application/json").header("Authorization", authorizations).execute();
		if (resp.isOk())
			return resp.body();
		return null;
	}

	public static List<Map<String, Object>> assemble(MinioFrame minioFrame, String ip, String username, String password, Integer number, Long startTime, Integer doorDirection) {
		String records = getRecord(ip, username, password, number, startTime);
		if (ToolUtil.isNotEmpty(records)) {
			System.err.println(records);
			Map<String, Object> record = new HashMap<>();
			// 解析数据(处理全部数据)
			String[] orignalArray = records.split("\r\n");
			for (int i = 0; i < orignalArray.length; i++) {
				String orignalItem = orignalArray[i];
				if (orignalItem.contains("=") && orignalItem.contains("[")) {
					String[] item = orignalItem.split("=");
					if (item != null && item.length == 2)
						record.put(item[0], item[1]);
				}
			}
			Set<String> userIdSet = new HashSet<String>();
			List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
			for (int i = 0; i < number; i++) {
				if (record.containsKey("records[" + i + "].CreateTime")) {
					Map<String, Object> item = new HashMap<String, Object>();
					if (record.containsKey("records[" + i + "].Door"))
						item.put("doorNo", record.get("records[" + i + "].Door"));
					if (record.containsKey("records[" + i + "].UserID") && record.get("records[" + i + "].UserID") != null) {
						item.put("userId", record.get("records[" + i + "].UserID"));
						userIdSet.add(String.valueOf(record.get("records[" + i + "].UserID")));
					}
					if (record.containsKey("records[" + i + "].CardName"))
						item.put("userName", record.get("records[" + i + "].CardName"));
					if (record.containsKey("records[" + i + "].UserID"))
						item.put("cardNo", record.get("records[" + i + "].CardNo"));
					if (record.containsKey("records[" + i + "].CreateTime"))
						item.put("cardTime", String.valueOf(record.get("records[" + i + "].CreateTime")) + "000");
					if (ObjectUtil.isNotEmpty(doorDirection)) {
						item.put("direct", doorDirection == 1 ? "进门" : "出门");
					}else {
						if (record.containsKey("records[" + i + "].Type")) {
							item.put("direct", String.valueOf(record.get("records[" + i + "].Type")).equals("Entry") ? "进门" : "出门");
						}
					}
					if (record.containsKey("records[" + i + "].Status"))
						if (record.get("records[" + i + "].Status") != null) {
							System.err.println("status:" + record.get("records[" + i + "].Status"));
							String status = record.get("records[" + i + "].Status").toString();
							item.put("status", (status.equals("0") ? 1 : 0));
						}
					/*
					大华:Method=15刷脸 21密码 1刷卡 0管理员密码
					我们的:
					 */
					if (record.containsKey("records[" + i + "].Method")) {
						if (record.get("records[" + i + "].Method") != null) {
							String method = record.get("records[" + i + "].Method").toString();
							item.put("openType", method);
						}
					}
					if (record.containsKey("records[" + i + "].URL"))
						if (record.get("records[" + i + "].URL") != null) {
							System.err.println("URL:" + record.get("records[" + i + "].URL"));
							String headUrl = record.get("records[" + i + "].URL").toString();
							String picurl = minioFrame.upload(inputStreamToMultipartFile(CaptureUtil.getPicurl(ip, username, password, headUrl), getDate() + ".jpg"), null);
							if (ToolUtil.isNotEmpty(picurl))
								item.put("headUrl", picurl); ///SnapShotFilePat…100_20250303093921232.jpg?timestamp=1740966278054
						}
					result.add(item);
				}
			}
			return result;
		}
		return null;
	}

	public static List<Map<String, Object>> assemble(MinioFrame minioFrame, Map<String, String> userIdFaces, String ip, String username, String password, Integer number, Long startTime, Integer doorDirection) {
		String records = getRecord(ip, username, password, number, startTime);
		if (ToolUtil.isNotEmpty(records)) {
			System.err.println(records);
			Map<String, Object> record = new HashMap<>();
			// 解析数据(处理全部数据)
			String[] orignalArray = records.split("\r\n");
			for (int i = 0; i < orignalArray.length; i++) {
				String orignalItem = orignalArray[i];
				if (orignalItem.contains("=") && orignalItem.contains("[")) {
					String[] item = orignalItem.split("=");
					if (item != null && item.length == 2)
						record.put(item[0], item[1]);
				}
			}
			Set<String> userIdSet = new HashSet<String>();
			List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
			for (int i = 0; i < number; i++) {
				if (record.containsKey("records[" + i + "].CreateTime")) {
					Map<String, Object> item = new HashMap<String, Object>();
					if (record.containsKey("records[" + i + "].Door"))
						item.put("doorNo", record.get("records[" + i + "].Door"));
					if (record.containsKey("records[" + i + "].UserID") && record.get("records[" + i + "].UserID") != null) {
						item.put("userId", record.get("records[" + i + "].UserID"));
						userIdSet.add(String.valueOf(record.get("records[" + i + "].UserID")));
					}
					if (record.containsKey("records[" + i + "].CardName"))
						item.put("userName", record.get("records[" + i + "].CardName"));
					if (record.containsKey("records[" + i + "].UserID"))
						item.put("cardNo", record.get("records[" + i + "].CardNo"));
					if (record.containsKey("records[" + i + "].CreateTime"))
						item.put("cardTime", String.valueOf(record.get("records[" + i + "].CreateTime")) + "000");
					if (record.containsKey("records[" + i + "].Type"))
						item.put("direct", String.valueOf(record.get("records[" + i + "].Type")).equals("Entry") ? "进门" : "出门");
					if (record.containsKey("records[" + i + "].Status"))
						if (record.get("records[" + i + "].Status") != null) {
							System.err.println("status:" + record.get("records[" + i + "].Status"));
							String status = record.get("records[" + i + "].Status").toString();
							item.put("status", (status.equals("0") ? 1 : 0));
						}
					if (record.containsKey("records[" + i + "].URL"))
						if (record.get("records[" + i + "].URL") != null) {
							String headUrl = record.get("records[" + i + "].URL").toString();
							String urlString = "http://" + ip + "/RPC2_Loadfile" + headUrl;
							System.err.println("URL:" + record.get("records[" + i + "].URL"));
							item.put("headUrl", "http://" + ip + "/RPC2_Loadfile" + headUrl); // http://192.168.0.166/RPC2_Loadfile/SnapShotFilePat…100_20250303093921232.jpg?timestamp=1740966278054
						}
					result.add(item);
				}
			}
			if (result != null && result.size() > 0) {
				if (userIdSet != null && userIdSet.size() > 0) {
					List<String> userIds = new ArrayList(userIdSet);
					String faces = getFace(ip, username, password, userIds);
					if (ToolUtil.isNotEmpty(faces)) {
						String[] orignals = faces.split("\r\n");
						Map<String, Object> faceRecord = new HashMap<>();
						for (int i = 0; i < orignals.length; i++) {
							String[] item = orignals[i].split("=");
							if (item != null && item.length == 2)
								faceRecord.put(item[0], item[1]);
						}
						for (int i = 0; i < userIds.size(); i++) {
							String itemId = String.valueOf(faceRecord.get("FaceDataList[" + i + "].UserID"));
							Object itemFace = faceRecord.get("FaceDataList[" + i + "].PhotoData[0]");
							if (itemFace != null) {
								if (!userIdFaces.containsKey(itemId)) {
									byte[] decodedBytes = Base64.decodeBase64(String.valueOf(itemFace));
									try (ByteArrayInputStream byteArrInput = new ByteArrayInputStream(decodedBytes)) {
										if (minioFrame == null) {
											System.err.println("minio is null,file:" + getDate() + ".jpg");
											log.error("minio is null");
										} else {
											String picurl = minioFrame.upload(inputStreamToMultipartFile(byteArrInput, getDate() + ".jpg"), null);
											userIdFaces.put(itemId, picurl);
											System.err.println(picurl);
										}
									} catch (IOException e) {
										e.printStackTrace();
									}
								}
							}
						}
						result.stream().forEach((item) -> {
							String userId = DataConvertUtil.getObjectStr(item, "userId");
							if (ToolUtil.isNotEmpty(userId) && userIdFaces.containsKey(userId))
								userIdFaces.put("headUrl", userIdFaces.get(userId));
							if (ToolUtil.isNotEmpty(userId))
								item.put("headUrl", userIdFaces.get(userId));
						});
					}
				}
			}
			return result;
		}
		return null;
	}

	public static String getDate() {
		SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
		return simpleDate.format(new java.util.Date()).replace(" ", "_").replace(":", "-");
	}

	private static MultipartFile inputStreamToMultipartFile(InputStream inputStream, String fileName) {
		try {
			return new MockMultipartFile(fileName, fileName, "image/jpeg", inputStream);
		} catch (IOException e) {
			log.error("输入流转文件失败:", e);
		}
		return null;
	}


	public static void main(String[] args) {

	}



}
